Go 被稱為是現代版的 C 語言,所以 C 語言的一些傳統?特色?在 Go 裡面也是可以看見
像是今天要介紹的 Pointer 指標,有學過 C 語言的一定不陌生
只不過 Go 的 Pointer 不像 C 語言一樣,會需要手動釋放記憶體,也沒有指標運算
下面就來實際操作吧!
這邊我們透過 A Tour of Go 上的官方範例來做講解
package main
import "fmt"
func main() {
i, j := 42, 2701
p := &i // 宣告 p 指向 i 的記憶體位址
fmt.Println(*p) // 印出 指標 p 指向的值 (i)
*p = 21 // 修改 指標 p 的值 (直接從 i 的記憶體位址修改)
fmt.Println(i) // 印出修改後的 i 值
p = &j // 宣告 p 指向 j 的記憶體位址
*p = *p / 37 // 修改 指標 p 的值 (直接從 j 的記憶體位址修改)
fmt.Println(j) // 印出修改後的 j 值
}
/* 輸出結果
42 // Line 9
21 // Line 11
73 // Line 15
*/
可以看到官方範例內提供了兩組範例,下面就來逐行講解
i
、j
,並給值 (Line 6)&i
(Line 8)*p
指向的值,也就是 變數 i (Line 9)*p
的值,也就是 直接從 i 的記憶體位址修改 (Line 10)i
、j
,並給值 (Line 6)&j
(Line 13)*p
的值,也就是 直接從 j 的記憶體位址修改 (Line 14)除了透過上面的方式來建立指標外,我們也可以透過動態記憶體分配來建立指標
直接來看範例吧
package main
import "fmt"
func main() {
ptr := new(int) // 宣告一個 int 的指標
fmt.Println(ptr) // 印出 ptr 的記憶體位址
fmt.Println(*ptr) // 印出 ptr 的記憶體位址所指向的值
*ptr = 10 // 將 ptr 的記憶體位址所指向的值設為 10
fmt.Println(ptr) // 印出 ptr 的記憶體位址
fmt.Println(*ptr) // 印出 ptr 的記憶體位址所指向的值
}
&ptr
(Line 8)&ptr
所指向的值 *ptr
(Line 9)&ptr
所指向的值 *ptr
設為 10 (Line 11)&ptr
(Line 12)&ptr
所指向的值 *ptr
(Line 13)可能會有人好奇說,為什麼不使用 make
來建立
這是因為兩者用途就不一樣
我們可以從兩者的 function 描述來看出差異
func new(Type) *Type
The new built-in function allocates memory. The first argument is a type, not a value, and the value returned is a pointer to a newly allocated zero value of that type.
func make(t Type, size ...IntegerType) Type
The make built-in function allocates and initializes an object of type slice, map, or chan (only). Like new, the first argument is a type, not a value. Unlike new, make's return type is the same as the type of its argument, not a pointer to it.
new | make | |
---|---|---|
用途 | 分配記憶體空間 | 分配與初始化物件的型別 |
回傳值 | 指標 | 物件的型別 |
今天簡單介紹了 Go 的 pointer 用法
也比較了 new 與 make 之間的差異
當變數較大時,傳遞指標會比起傳遞整個變數來得更有效率喔
下一篇會來介紹 functions 的用法
明天見~